"""
配置管理器

负责加载、验证和管理系统配置
"""

import yaml
import os
from typing import Dict, Any
from loguru import logger
from pathlib import Path


class ConfigManager:
    """配置管理器"""
    
    def __init__(self, config_path: str):
        """
        初始化配置管理器
        
        Args:
            config_path: 配置文件路径
        """
        self.config_path = Path(config_path)
        self.config = {}
        self._load_config()
    
    def _load_config(self):
        """加载配置文件"""
        try:
            if not self.config_path.exists():
                logger.warning(f"配置文件不存在: {self.config_path}")
                self._create_default_config()
            
            with open(self.config_path, 'r', encoding='utf-8') as f:
                self.config = yaml.safe_load(f)
            
            # 验证配置
            self._validate_config()
            
            logger.info(f"配置文件已加载: {self.config_path}")
            
        except Exception as e:
            logger.error(f"配置文件加载失败: {e}")
            self._create_default_config()
    
    def _create_default_config(self):
        """创建默认配置"""
        self.config = {
            'system': {
                'name': 'Vibration Keyboard System',
                'version': '1.0.0',
                'debug': True
            },
            'hardware': {
                'device': 'Huawei Watch 2',
                'sensors': {
                    'accelerometer': {
                        'enabled': True,
                        'sample_rate': 100,
                        'range': [-20, 20]
                    },
                    'gyroscope': {
                        'enabled': True,
                        'sample_rate': 100,
                        'range': [-2000, 2000]
                    }
                }
            },
            'vibration_model': {
                'horizontal': {
                    'direction': 'left_to_right',
                    'attenuation_coefficient': 0.1,
                    'propagation_speed': 1000,
                    'step_size': 0.01
                },
                'vertical': {
                    'direction': 'bottom_to_top',
                    'attenuation_coefficient': 0.15,
                    'propagation_speed': 800,
                    'step_size': 0.01
                },
                'decay': {
                    'initial_amplitude': 1.0,
                    'decay_model': 'exponential'
                }
            },
            'signal_processing': {
                'endpoint_detection': {
                    'energy_threshold_high': 0.8,
                    'energy_threshold_low': 0.3,
                    'zero_crossing_threshold': 0.5,
                    'min_silence_length': 0.1,
                    'min_speech_length': 0.05,
                    'center_clip_threshold': 0.01
                },
                'median_filter': {
                    'window_size': 5,
                    'enabled': True
                },
                'dtw': {
                    'window_size': 10,
                    'step_pattern': 'symmetric2',
                    'distance_metric': 'euclidean',
                    'normalization': True
                },
                'energy_entropy': {
                    'frame_length': 256,
                    'frame_shift': 128,
                    'window_type': 'hamming',
                    'fft_size': 512,
                    'energy_constant': 1.0
                }
            },
            'feature_extraction': {
                'time_domain': {
                    'enabled': True,
                    'features': ['amplitude', 'energy', 'zero_crossing_rate', 'rms', 'peak_to_peak']
                },
                'frequency_domain': {
                    'enabled': True,
                    'features': ['power_spectral_density', 'spectral_centroid', 'spectral_rolloff', 'spectral_bandwidth', 'mfcc'],
                    'mfcc': {
                        'n_mfcc': 13,
                        'n_fft': 512,
                        'hop_length': 128,
                        'n_mels': 40
                    }
                }
            },
            'key_recognition': {
                'knn': {
                    'n_neighbors': 5,
                    'weights': 'uniform',
                    'algorithm': 'auto',
                    'leaf_size': 30,
                    'metric': 'minkowski',
                    'p': 2
                },
                'classification': {
                    'confidence_threshold': 0.7,
                    'max_candidates': 3,
                    'voting_method': 'weighted'
                }
            },
            'real_time_update': {
                'sample_update': {
                    'enabled': True,
                    'max_samples_per_key': 100,
                    'update_threshold': 0.8,
                    'outlier_detection': True
                },
                'outlier_detection': {
                    'method': 'isolation_forest',
                    'contamination': 0.1,
                    'random_state': 42
                },
                'model_adaptation': {
                    'learning_rate': 0.1,
                    'adaptation_threshold': 0.6,
                    'max_iterations': 1000
                }
            },
            'virtual_keyboard': {
                'layout': {
                    'rows': 3,
                    'columns': 10,
                    'key_size': [0.8, 0.8],
                    'key_spacing': 0.2
                },
                'key_mapping': {
                    'row1': ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'],
                    'row2': ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'backspace'],
                    'row3': ['shift', 'z', 'x', 'c', 'v', 'b', 'n', 'm', 'space', 'enter']
                }
            },
            'data_storage': {
                'format': 'hdf5',
                'compression': 'gzip',
                'compression_level': 6,
                'paths': {
                    'raw_data': 'data/raw/',
                    'processed_data': 'data/processed/',
                    'models': 'models/',
                    'logs': 'logs/'
                },
                'retention': {
                    'max_days': 30,
                    'max_size_gb': 10
                }
            },
            'logging': {
                'level': 'INFO',
                'format': '{time:YYYY-MM-DD HH:mm:ss} | {level} | {name}:{function}:{line} | {message}',
                'rotation': '10 MB',
                'retention': '7 days',
                'compression': 'zip'
            },
            'performance': {
                'monitoring': {
                    'enabled': True,
                    'sample_interval': 1.0,
                    'metrics': ['cpu_usage', 'memory_usage', 'processing_time', 'accuracy']
                },
                'thresholds': {
                    'max_processing_time': 0.1,
                    'min_accuracy': 0.8,
                    'max_memory_usage': 0.8
                }
            }
        }
        
        # 保存默认配置
        self.save_config()
    
    def _validate_config(self):
        """验证配置"""
        required_sections = [
            'system', 'hardware', 'vibration_model', 'signal_processing',
            'feature_extraction', 'key_recognition', 'real_time_update',
            'virtual_keyboard', 'data_storage', 'logging', 'performance'
        ]
        
        for section in required_sections:
            if section not in self.config:
                logger.warning(f"配置缺少必要部分: {section}")
    
    def get_config(self) -> Dict[str, Any]:
        """
        获取配置
        
        Returns:
            配置字典
        """
        return self.config
    
    def get_section(self, section: str) -> Dict[str, Any]:
        """
        获取配置部分
        
        Args:
            section: 配置部分名称
            
        Returns:
            配置部分字典
        """
        return self.config.get(section, {})
    
    def update_config(self, updates: Dict[str, Any]):
        """
        更新配置
        
        Args:
            updates: 更新内容
        """
        self._update_dict(self.config, updates)
        self.save_config()
        logger.info("配置已更新")
    
    def _update_dict(self, target: Dict, updates: Dict):
        """递归更新字典"""
        for key, value in updates.items():
            if key in target and isinstance(target[key], dict) and isinstance(value, dict):
                self._update_dict(target[key], value)
            else:
                target[key] = value
    
    def save_config(self):
        """保存配置到文件"""
        try:
            # 确保目录存在
            self.config_path.parent.mkdir(parents=True, exist_ok=True)
            
            with open(self.config_path, 'w', encoding='utf-8') as f:
                yaml.dump(self.config, f, default_flow_style=False, allow_unicode=True)
            
            logger.info(f"配置已保存到: {self.config_path}")
            
        except Exception as e:
            logger.error(f"配置保存失败: {e}")
    
    def reset_config(self):
        """重置为默认配置"""
        self._create_default_config()
        logger.info("配置已重置为默认值")
    
    def __str__(self) -> str:
        return f"ConfigManager(config_path={self.config_path})"
    
    def __repr__(self) -> str:
        return self.__str__() 